#include <my_header.h>
#if 0
 实现一个函数(客户端): (可以使用阻塞的recv实现, 也可以使用非阻塞的recv实现)
recvn(int netfd, void *buf, int length)
函数最终目的: 让我们最终可以向buf指向的内存中接收指定长度(length)的数据。

#endif
/* Usage: ./1_recvn */
// 函数：recvn
// 描述：从指定的套接字中接收总共指定字节数的数据
// 参数：
//   sockfd - 套接字文件描述符
//   buf - 存储接收到数据的缓冲区
//   total - 要接收的总字节数
// 返回值：
//   如果接收成功返回 0；如果连接关闭返回 1

int recvn(int sockfd, void *buf, long total) {
    char *p = (char *)buf; // 将 buf 转换为 char* 类型，便于按字节操作
    long cursize = 0; // 当前已接收的字节数

    // 循环接收数据，直到接收到 total 个字节
    while (cursize < total) {
        // 调用 recv 函数从套接字中接收数据
        ssize_t sret = recv(sockfd, p + cursize, total - cursize, 0);
        // ssize_t sret = recv(sockfd, p+cursize, total-curzie, MSG_WAITALL);
        // 如果 recv 返回 0，表示对端已经关闭连接
        if (sret == 0) {
            return 1; // 返回 1 表示连接关闭
        }

         // 更新已接收的字节数
        cursize += sret; // 将当前接收的字节数加到 cursize
    }
    return 0; // 返回 0 表示成功接收所有数据
}

#if 0
p + cursize:

这里，p 是指向接收缓冲区的指针，类型是 char *。通过 p + cursize，我们得到一个指向缓冲区中要存储接收数据的
特定位置的指针。cursize 表示当前已经接收到的字节数，因此 p + cursize 将指向缓冲区中下一个空闲的位置，
准备在这里写入新的数据。

例如，如果已经接收到 10 字节数据，cursize 的值将是 10，在这个情况下，p + cursize 就是 buf[10]，
这意味着新的数据将被写入缓冲区的第 11 个字节位置。

total - cursize:

该表达式计算剩余需要接收的数据字节数。total 是期望接收的总字节数，而 cursize 是当前已经接收到的字节数。
因此，total - cursize 给出了还需要接收多少字节的数据。
例如，假设 total 是 100 字节，而已经接收了 30 字节（即 cursize 为 30），那么 total - cursize 就会是 70，
这意味着 recv 在这一轮要尽力接收剩下的 70 字节。
#endif
